<?php

namespace app\user\controller;

use app\admin\service\ReportService;
use app\admin\service\UserService;
use app\BaseController;
use app\model\ConfigModel;
use app\model\ConsultBlacklistModel;
use app\model\ConsultEvaluateModel;
use app\model\ConsultOfflineModel;
use app\model\ConsultOfflineTaskModel;
use app\model\ConsultOnlineMessageModel;
use app\model\ConsultOnlineModel;
use app\model\ConsultQuestionModel;
use app\model\ConsultTimeModel;
use app\model\MessageModel;
use app\model\UserModel;
use app\model\UserTagModel;
use app\socket\Server;
use app\user\service\ConsultService;
use think\App;
use think\swoole\Websocket;

class Consult extends BaseController
{
    public function __construct(App $app)
    {
        parent::__construct($app);
    }

    /**
     * 线上咨询师列表
     * @return bool|string
     */
    public function OnlineConsultantList(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            if (!empty($param['name'])) {
                $where[] = ['name', 'like', '%' . $param['name'] . '%'];
            }
            if (!empty($param['sex'])) {
                $where[] = ['sex','=',$param['sex']];
            }
            if (!empty($param['age'])) {
                $where[] = ['age','=',$param['age']];
            }
            if (!empty($param['tag_id'])) {
                $UserTagModel = new UserTagModel();
                $uids = $UserTagModel->where(['tag_id' => $param['tag_id']])->column('uid');
                if(!empty($uids)){
                    $where[] = ['id','in',$uids];
                }else{
                    $where[] = ['id','=',-1];
                }
            }
            $ConsultBlacklistModel = new ConsultBlacklistModel();
            $consult_id = $ConsultBlacklistModel->where('uid','=',$this->userData['id'])->column('consult_id');
            if (!empty($consult_id)) {
                $where[] = ['id','not in',$consult_id];
            }
            $where[] = ['unit_id','=',$this->userData['unit_id']];
            $where[] = ['role_mode','=',2];
            $UserModel = new UserModel();
            $data = $UserModel->where($where)->with([
                'userTag' => function($query){
                    $query->with(['tag']);
                }
            ])->paginate($param['pageSize'])->toArray();
            $ConsultTimeModel = new ConsultTimeModel();
            $UserService = new UserService($this->app);
            $NotDelDepartmentAll = $UserService->getNotDelDepartmentAffiliationAll($this->userData['unit_id']);
            $ConsultOnlineModel = new ConsultOnlineModel();
            foreach ($data['data'] as &$item){
                $item['me_consult_count'] = $ConsultOnlineModel->where([
                    ['consult_id','=',$item['id']],
                    ['uid','=',$this->userData['id']]
                ])->count();
                $time_department_id = $ConsultTimeModel->where('consult_id','=',$item['id'])->column('department_id');
                $time_department_id = array_unique($time_department_id);
                if (in_array(0, $time_department_id)) {
                    $item['department_name'] = '所有部门';
                }else{
                    foreach ($time_department_id as $department_id){
                        if (!empty($item['department_name'])){
                            $item['department_name'] .= '、'.$NotDelDepartmentAll[$department_id]['all_name'];
                        }else{
                            $item['department_name'] = $NotDelDepartmentAll[$department_id]['all_name'];
                        }
                    }
                }
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 问题类型选择器
     * @return bool|string
     */
    public function questionSelector(): bool|string
    {
        try {
            $where = [];
            $where[] = ['status', '=', 1];
            $where[] = ['unit_id','=',$this->userData['unit_id']];
            $ConsultQuestionModel = new ConsultQuestionModel();
            $data = $ConsultQuestionModel->field('id,name')->where($where)->order('id desc')->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 提交线上咨询
     * @param Websocket $websocket
     * @return bool|string
     */
    public function OnlineSubmitConsultation(Websocket $websocket): bool|string
    {
        $ConsultOnlineModel = new ConsultOnlineModel();
        $ConsultOnlineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'consult_id|咨询师' => 'require|integer|max:11',
                'question_id|问题类型' => 'require|integer|max:11',
                'question|问题详情' => 'require',
            ]);
            $param['uid'] = $this->userData['id'];
            $param['unit_id'] = $this->userData['unit_id'];
            $param['time'] = time();
            $id = $ConsultOnlineModel->insertGetId($param);
            //系统消息
            $MessageModel = new MessageModel();
            $MessageModel->insert([
                'uid' => $param['consult_id'],
                'type' => 17,
                'title' => '发起咨询',
                'content' => $this->userData['name'].'用户向您发起了线上心理咨询，咨询问题：'.$param['question'],
                'time' => time()
            ]);
            $ConsultOnlineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$param['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $id,
                    'type' => 1
                ]
            ]),$websocket);
            $socketServer->push($fd,json_encode([
                'type' => 'message',
                'content' => [
                    'type' => 17,
                    'title' => '发起咨询',
                    'content' => $this->userData['name'].'用户向您发起了线上心理咨询，咨询问题：'.$param['question'],
                    'img' => match (17){
                        3,4,5,7,8,9,10 => '/icon_task/202411/07_1730960087672c5ad715646.png',//测评任务消息
                        6,11, 1, 2, 14, 15, 16,23 => '/icon_task/202411/07_1730960430672c5c2ee2c98.png',//预警报告消息-系统通知-公告-危机干预
                        17 => '/icon_task/202411/07_1730944047672c1c2fd624c.png',//预约咨询消息
                        22 => '/icon_task/202411/07_1730941588672c1294c2e1e.png',//物联网消息
                    },
                    'time' => time()
                ]
            ]),$websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOnlineModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下咨询师列表
     * @return bool|string
     */
    public function OfflineConsultantList(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            $timeWhere = [];
            if (!empty($param['tag_id'])) {
                $UserTagModel = new UserTagModel();
                $uids = $UserTagModel->where(['tag_id' => $param['tag_id']])->column('uid');
                if (!empty($uids)) {
                    $where[] = ['id','in',$uids];
                }else{
                    return success();
                }
            }
            if (!empty($param['date'])) {
                $timeWhere[] = ['date','=',date('Ymd',strtotime($param['date']))];
            }else{
                $timeWhere[] = ['date','>=',date('Ymd')];
            }
            $timeWhere[] = ['unit_id','=',$this->userData['unit_id']];
            $ConsultTimeModel = new ConsultTimeModel();
            $consult_ids = $ConsultTimeModel->where($timeWhere)->distinct(true)->column('consult_id');
            if (!empty($consult_ids)) {
                $ConsultBlacklistModel = new ConsultBlacklistModel();
                $consult_id = $ConsultBlacklistModel->where('uid','=',$this->userData['id'])->column('consult_id');
                if (!empty($consult_id)) {
                    $consult_ids = array_diff($consult_ids,$consult_id);
                }
                $where[] = ['id', 'in', $consult_ids];
            }else{
                $where[] = ['id', '=', -1];
            }
            $where[] = ['role_mode', '=', 2];
            $where[] = ['unit_id', '=', $this->userData['unit_id']];
            $UserModel = new UserModel();
            $data = $UserModel->where($where)->field('id,name,avatar,age,sex')->with([
                'userTag' => function($query){
                    $query->with(['tag']);
                }
            ])->select()->toArray();
            $UserService = new UserService($this->app);
            $NotDelDepartmentAll = $UserService->getNotDelDepartmentAffiliationAll($this->userData['unit_id']);
            $ConsultOfflineModel = new ConsultOfflineModel();
            foreach ($data as &$item){
                $item['me_consult_count'] = $ConsultOfflineModel->where([
                    ['consult_id','=',$item['id']],
                    ['uid','=',$this->userData['id']]
                ])->count();
                $item['responsible_department'] = '--';
                $time_department_id = $ConsultTimeModel->where('consult_id','=',$item['id'])->column('department_id');
                $time_department_id = array_unique($time_department_id);
                if (in_array(0, $time_department_id)) {
                    $item['responsible_department'] = '所有部门';
                }else{
                    $time_department_id = $UserService->getDepartmentAllLowerLevelIds($this->userData['unit_id'],$time_department_id);
                    $responsibleDepartmentData = [];
                    foreach ($time_department_id as $department_id){
                        $responsibleDepartmentData[] = $NotDelDepartmentAll[$department_id]['all_name'];
                    }
                    $item['responsible_department'] = implode('、',$responsibleDepartmentData);
                }
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约咨询提交
     * @param Websocket $websocket
     * @return bool|string
     */
    public function OfflineSubmitConsultation(Websocket $websocket): bool|string
    {
        $ConsultOfflineModel = new ConsultOfflineModel();
        $ConsultOfflineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'consult_id|咨询师' => 'require|integer|max:11',
                'question_id|问题类型' => 'require|integer|max:11',
                'question|问题详情' => 'require',
                'type|预约人情况' => 'require',
                'time_id|预约时间' => 'require|integer|max:11',
                'address|预约地址' => 'require',
                'uid|预约人' => 'require|integer|max:11',
                'time|提交时间' => 'require|integer|max:11',
            ]);
            $UserModel = new UserModel();
            $UserInfo = $UserModel->find($param['uid']);
            if ($UserInfo->role_mode != 3) throw new \Exception('只能普通用户预约！');
            $ConsultTimeModel = new ConsultTimeModel();
            $TimeInfo = $ConsultTimeModel->find($param['time_id']);
            if (!$TimeInfo) throw new \Exception('参数错误！');
            if ($TimeInfo->start_time < time()) throw new \Exception('排班时间已过期！');
            if ($TimeInfo->is_reservation == 1) throw new \Exception('该时段已被他人预约！');
            $ConfigModel = new ConfigModel();
            $config = $ConfigModel->where([
                ['unit_id', '=', $this->userData['unit_id']],
                ['key','=','consult']
            ])->value('value')??'';
            $config = json_decode($config,true);
            if ($config['in_advance'] == 1){
                if ($TimeInfo->start_time < time() + (3600*intval($config['in_advance_time'])))
                    throw new \Exception('需提前'.$config['in_advance_time'].'小时预约！');
            }
            $param['unit_id'] = $this->userData['unit_id'];
            $offline_id = $ConsultOfflineModel->insertGetId($param);
            $TimeInfo->offline_id = $offline_id;
            $TimeInfo->is_reservation = 1;
            $TimeInfo->reservation_time = time();
            $TimeInfo->uid = $this->userData['id'];
            $TimeInfo->save();
            //系统消息
            $MessageData = [];
            $MessageModel = new MessageModel();
            $MessageData[] = [
                'uid' => intval($param['consult_id']),
                'type' => 18,
                'title' => '发起预约',
                'content' => '用户'.$this->userData['name'].'向您预约了'.date('Y-m-d',$TimeInfo['start_time']).'日期'.date('H:i:s',$TimeInfo['start_time']).'时间的线下心理咨询服务，请及时查看并回复。',
                'time' => time()
            ];
            $user_name = $UserModel->where('id','=',$param['consult_id'])->value('name');
            $MessageData[] = [
                'uid' => $this->userData['id'],
                'type' => 18,
                'title' => '发起预约',
                'content' => '您于'.date('Y-m-d',$TimeInfo['start_time']).'日期'.date('H:i:s',$TimeInfo['start_time']).'时间向'.$user_name.'咨询师提交的线下预约申请，已预约成功，请按时赴约。',
                'time' => time()
            ];
            $MessageModel->insertAll($MessageData);
            $ConsultOfflineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$param['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $offline_id,
                    'type' => 1
                ]
            ]),$websocket);
            $socketServer->push($fd,json_encode([
                'type' => 'message',
                'content' => [
                    'type' => 18,
                    'title' => '发起预约',
                    'content' => '用户'.$this->userData['name'].'向您预约了'.date('Y-m-d',$TimeInfo['start_time']).'日期'.date('H:i:s',$TimeInfo['start_time']).'时间的线下心理咨询服务，请及时查看并回复。',
                    'img' => match (18){
                        3,4,5,7,8,9,10 => '/icon_task/202411/07_1730960087672c5ad715646.png',//测评任务消息
                        6,11, 1, 2, 14, 15, 16,23 => '/icon_task/202411/07_1730960430672c5c2ee2c98.png',//预警报告消息-系统通知-公告-危机干预
                        17,18 => '/icon_task/202411/07_1730944047672c1c2fd624c.png',//预约咨询消息
                        22 => '/icon_task/202411/07_1730941588672c1294c2e1e.png',//物联网消息
                    },
                    'time' => time()
                ]
            ]),$websocket);
            $fd = $socketServer->uidGetFd([$this->userData['id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'message',
                'content' => [
                    'type' => 18,
                    'title' => '发起预约',
                    'content' => '您于'.date('Y-m-d',$TimeInfo['start_time']).'日期'.date('H:i:s',$TimeInfo['start_time']).'时间向'.$user_name.'咨询师提交的线下预约申请，已预约成功，请按时赴约。',
                    'img' => match (18){
                        3,4,5,7,8,9,10 => '/icon_task/202411/07_1730960087672c5ad715646.png',//测评任务消息
                        6,11, 1, 2, 14, 15, 16,23 => '/icon_task/202411/07_1730960430672c5c2ee2c98.png',//预警报告消息-系统通知-公告-危机干预
                        17,18 => '/icon_task/202411/07_1730944047672c1c2fd624c.png',//预约咨询消息
                        22 => '/icon_task/202411/07_1730941588672c1294c2e1e.png',//物联网消息
                    },
                    'time' => time()
                ]
            ]),$websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOfflineModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录
     * @return bool|string
     */
    public function OnlineConsultationRecord(): bool|string
    {
        try {
            $param = $this->request->param();
            $where = [];
            if (!empty($param['question_id'])) {
                $where[] = ['question_id', '=', $param['question_id']];
            }
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            }else{
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', '=', $param['consult_id']];
            }
            if (!empty($param['question'])) {
                $where[] = ['question', 'like', '%'.$param['question'].'%'];
            }
            if (isset($param['is_end']) && strlen($param['is_end']) > 0) {
                $where[] = ['is_end', '=', $param['is_end']];
            }
            if (!empty($param['name'])){
                $UserModel = new UserModel();
                $uid = $UserModel->where('name','like', '%'.$param['name'].'%')->column('id');
                if (!empty($uid)){
                    $where[] = ['consult_id', 'in', $uid,'or'];
                    $where[] = ['question', 'like', '%'.$param['name'].'%','or'];
                }else{
                    $where[] = ['question', 'like', '%'.$param['name'].'%'];
                }
            }
            $where[] = ['uid','=',$this->userData['id']];
            $where[] = ['user_del', '=', 0];
            $ConsultOnlineModel = new ConsultOnlineModel();
            $query = $ConsultOnlineModel->where($where);
            $data = $query->with([
                'consult','questionName'
            ])->order('id desc')->paginate($param['pageSize'])->toArray();
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录-详情
     * @return bool|string
     */
    public function onlineInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOnlineModel = new ConsultOnlineModel();
            $data = $ConsultOnlineModel->with([
                'questionName',
                'consult',
                'user'
            ])->find($id);
            if (!$data) throw new \Exception('参数错误！');
            $data->save([
                'user_dot' => 0
            ]);
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询记录-删除
     * @return bool|string
     */
    public function OnlineConsultationRecordDel(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOnlineModel = new ConsultOnlineModel();
            if (is_array($id)){
                $ConsultOnlineModel->where('id','in',$id)->update([
                    'user_del' => 1
                ]);
            }else{
                $ConsultOnlineModel->where('id','=',$id)->update([
                    'user_del' => 1
                ]);
            }
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询聊天内容
     * @return bool|string
     */
    public function OnlineMessage(): bool|string
    {
        $ConsultOnlineModel = new ConsultOnlineModel();
        $ConsultOnlineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'id|ID' => 'require'
            ]);
            $info = $ConsultOnlineModel->find($param['id']);
            if (!$info) throw new \Exception('记录已被删除！');
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $data = $ConsultOnlineMessageModel->where('online_id','=',$param['id'])->with([
                'user',
                'RatingScale'
            ])->select()->toArray();
            $dot = 0;
            foreach ($data as &$item){
                if ($item['type'] == 1 && $item['user_dot'] == 1){
                    $item['user_dot'] = 0;
                }else{
                    $dot = 1;
                }
            }
            $ConsultOnlineMessageModel->where([
                ['online_id','=',$param['id']],
                ['type','=',1]
            ])->update([
                'user_dot' => 0
            ]);
            if ($dot){
                $info->save([
                    'user_dot' => 0
                ]);
            }
            $ConsultOnlineModel->commit();
            return success($data);
        } catch (\Exception $e) {
            $ConsultOnlineModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-发送消息
     * @param Websocket $websocket
     * @return bool|string
     */
    public function onlineSendMessage(Websocket $websocket): bool|string
    {
        $ConsultOnlineModel = new ConsultOnlineModel();
        $ConsultOnlineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'online_id|咨询记录' => 'require|integer|max:11',
                'content|消息内容' => 'require',
            ]);
            $info = $ConsultOnlineModel->field('id,consult_id,is_blacklist,is_end')->find($param['online_id']);
            if(!$info) throw new \Exception('参数错误！');
            if ($info->is_end == 1) throw new \Exception('发送失败，会话已结束！');
            $info->admin_dot = 1;
            $info->save();
            $param['uid'] = $this->userData['id'];
            $param['who'] = 1;
            $param['time'] = time();
            $param['admin_dot'] = 1;
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $ConsultOnlineMessageModel->create($param);
            $ConsultOnlineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $param['online_id'],
                    'type' => 1
                ]
            ]),$websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOnlineModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录
     * @return bool|string
     */
    public function OfflineConsultationRecord(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'pageSize|每页显示数量' => 'require'
            ]);
            $ConsultOfflineModel = new ConsultOfflineModel();
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $where = [];
            if (!empty($param['question_id'])) {
                $where[] = ['question_id', '=', $param['question_id']];
            }
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            }else{
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', '=', $param['consult_id']];
            }
            if (isset($param['is_end']) && strlen($param['is_end']) > 0) {
                $where[] = ['is_end', '=', $param['is_end']];
            }
            if (isset($param['situation']) && strlen($param['situation']) > 0) {
                $where[] = ['situation', '=', $param['situation']];
            }
            if (!empty($param['question'])) {
                $where[] = ['question', 'like', '%'.$param['question'].'%'];
            }
            if (!empty($param['name'])){
                $UserModel = new UserModel();
                $uid = $UserModel->where('name','like', '%'.$param['name'].'%')->column('id');
                if (!empty($uid)){
                    $where[] = ['consult_id', 'in', $uid,'or'];
                    $where[] = ['question', 'like', '%'.$param['name'].'%','or'];
                }else{
                    $where[] = ['question', 'like', '%'.$param['name'].'%'];
                }
            }
            $where[] = ['uid','=',$this->userData['id']];
            $where[] = ['user_del','=',0];
            if (isset($param['pre_task']) && strlen($param['pre_task']) > 0) {
                $ids = $ConsultOfflineModel->where($where)->column('id');
                if ($param['pre_task'] == 0){
                    $offline_id = $ConsultOfflineTaskModel->where([
                        ['is_finish','=',0],
                        ['offline_id','in',$ids]
                    ])->column('offline_id');
                }else{
                    $offline_id = $ConsultOfflineTaskModel->where([
                        ['is_finish','=',1],
                        ['offline_id','in',$ids]
                    ])->column('offline_id');
                }
                $offline_id = array_unique($offline_id);
                $where[] = ['id','in',$offline_id];
            }
            if (isset($param['is_pre_task']) && strlen($param['is_pre_task']) > 0){
                $ids = $ConsultOfflineModel->where($where)->column('id');
                $offline_id = $ConsultOfflineTaskModel->where('offline_id','in',$ids)->column('offline_id');
                if ($param['is_pre_task'] == 0){
                    $offline_id = array_diff($ids,$offline_id);
                }else{
                    $offline_id = array_unique($offline_id);
                }
                $where[] = ['id','in',$offline_id];
            }
            $query = $ConsultOfflineModel->where($where);
            $data = $query->with([
                'consult','questionName','ConsultTime'
            ])->order('id desc')->paginate($param['pageSize'])->toArray();
            foreach ($data['data'] as &$item){
                $item['reservation_time'] = date('Y-m-d H:i',$item['reservation_start_time']).'-'.date('H:i',$item['reservation_end_time']);
                $item['task_count'] = $ConsultOfflineTaskModel->where('offline_id','=',$item['id'])->count();
                $item['task_complete_num'] = $ConsultOfflineTaskModel->where([
                    ['offline_id','=',$item['id']],
                    ['is_finish','=',1]
                ])->count();
            }
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-详情
     * @return bool|string
     */
    public function offlineInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineModel = new ConsultOfflineModel();
            $info = $ConsultOfflineModel->with([
                'consult',
                'ConsultTime',
                'task' => function ($query) {
                    $query->with(['RatingScale','ConsultOfflineResult']);
                },
                'questionName'
            ])->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->user_dot == 1){
                $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
                $is_dot = $ConsultOfflineTaskModel->where([
                    ['offline_id','=',$id],
                    ['user_dot','=',1]
                ])->value('id');
                if (!$is_dot){
                    $info->user_dot = 0;
                    $info->save();
                }
            }
            $info['appoinment_date'] = date('Y-m-d',$info['reservation_start_time']);
            $info['appoinment_period'] = date('H:i',$info['reservation_start_time']).'-'.date('H:i',$info['reservation_end_time']);
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-删除
     * @return bool|string
     */
    public function OfflineConsultationRecordDel(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineModel = new ConsultOfflineModel();
            if (is_array($id)){
                $ConsultOfflineModel->where('id','in',$id)->update([
                    'user_del' => 1
                ]);
            }else{
                $ConsultOfflineModel->where('id','=',$id)->update([
                    'user_del' => 1
                ]);
            }
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约记录-详情
     * @return bool|string
     */
    public function OfflineConsultationRecordInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineModel = new ConsultOfflineModel();
            $data = $ConsultOfflineModel->with([
                'ConsultTime',
                'task' => function($query){
                    $query->with(['RatingScale']);
                },
                'questionName'
            ])->find($id);
            if (!$data) throw new \Exception('参数错误！');
            if ($data->user_dot == 1){
                $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
                $is_dot = $ConsultOfflineTaskModel->where([
                    ['offline_id','=',$id],
                    ['user_dot','=',1]
                ])->value('id');
                if (!$is_dot){
                    $data->user_dot = 0;
                    $data->save();
                }
            }
            $data = $data->toArray();
            $data['reservation_time'] = date('Y-m-d H:i',$data['reservation_start_time']).'-'.date('H:i',$data['reservation_end_time']);
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 提交线上咨询测评任务答案
     * @param Websocket $websocket
     * @return bool|string
     */
    public function addConsultOnlineResult(Websocket $websocket): bool|string
    {
        $ConsultOnlineMessage = new ConsultOnlineMessageModel();
        $ConsultOnlineMessage->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'source_id|来源' => 'require|integer|max:11',
                'rating_scale_id|量表' => 'require|integer|max:11',
                'question_answer|答案' => 'require',
                'finish_used_time|用户完成用时' => 'require',
            ]);
            $info = $ConsultOnlineMessage->with(['ConsultOnline'])->find($param['source_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->is_finish == 1) throw new \Exception('不可重复答题！');
            $info->user_dot = 0;
            $info->save();
            $ConsultService = new ConsultService($this->app);
            if (!$ConsultService->generateReport([
                'source_id' => $param['source_id'],//来源id
                'company_id' => $this->userData['company_id'],//公司
                'areas_id' => $this->userData['areas_id'],//区域
                'unit_id' => $this->userData['unit_id'],//单位
                'uid' => $this->userData['id'],//测评人
                'rating_scale_id' => $param['rating_scale_id'],//量表ID
                'question_answer' => $param['question_answer'],//用户填写的答案
                'finish_used_time' => $param['finish_used_time'],//用户完成用时
            ],6)) throw new \Exception($ConsultService->message);
            $ConsultOnlineMessage->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultOnline',
                'content' => [
                    'id' => $info['online_id'],
                    'type' => 1
                ]
            ]),$websocket);
            return success(['result_id' => $ConsultService->ResultId]);
        } catch (\Exception $e) {
            $ConsultOnlineMessage->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 提交线下预约测评任务答案
     * @param Websocket $websocket
     * @return bool|string
     */
    public function addConsultOfflineResult(Websocket $websocket): bool|string
    {
        $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
        $ConsultOfflineTaskModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'source_id|来源' => 'require|integer|max:11',
                'rating_scale_id|量表' => 'require|integer|max:11',
                'question_answer|答案' => 'require',
                'finish_used_time|用户完成用时' => 'require',
            ]);
            $info = $ConsultOfflineTaskModel->with(['ConsultOffline'])->find($param['source_id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->is_finish == 1) throw new \Exception('不可重复答题！');
            $info->user_dot = 0;
            $info->save();
            $ConsultService = new ConsultService($this->app);
            if (!$ConsultService->generateReport([
                'source_id' => $param['source_id'],//来源id
                'company_id' => $this->userData['company_id'],//单位
                'areas_id' => $this->userData['areas_id'],//单位
                'unit_id' => $this->userData['unit_id'],//单位
                'uid' => $this->userData['id'],//测评人
                'rating_scale_id' => $param['rating_scale_id'],//量表ID
                'question_answer' => $param['question_answer'],//用户填写的答案
                'finish_used_time' => $param['finish_used_time'],//用户完成用时
            ],7)) throw new \Exception($ConsultService->message);
            $ConsultOfflineTaskModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $info['offline_id'],
                    'type' => 1
                ]
            ]),$websocket);
            return success(['result_id' => $ConsultService->ResultId]);
        } catch (\Exception $e) {
            $ConsultOfflineTaskModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询-查看测评结果
     * @return bool|string
     */
    public function OnlineViewResult(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $info = $ConsultOnlineMessageModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->result_read_auth == 0) throw new \Exception('暂无权限');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->OnlineReportInfo($info->result_id);
            if ($info->user_dot == 1){
                $info->user_dot = 0;
                $info->save();
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    public function OnlineViewResult2()
    {
        try {
            $id = $this->request->param('id');
            $ConsultOnlineMessageModel = new ConsultOnlineMessageModel();
            $info = $ConsultOnlineMessageModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->result_read_auth == 0) throw new \Exception('暂无权限');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->getOnlineEvaluationReportInfo($info->result_id);
            if ($info->user_dot == 1){
                $info->user_dot = 0;
                $info->save();
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约-查看测评结果
     * @return bool|string
     */
    public function OfflineViewResult(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $info = $ConsultOfflineTaskModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->result_read_auth == 0) throw new \Exception('暂无权限');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->OfflineReportInfo($info->result_id);
            if ($info->user_dot == 1){
                $info->user_dot = 0;
                $info->save();
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约-查看测评结果
     * @return bool|string
     */
    public function OfflineViewResult2(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ConsultOfflineTaskModel = new ConsultOfflineTaskModel();
            $info = $ConsultOfflineTaskModel->find($id);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->result_read_auth == 0) throw new \Exception('暂无权限');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->getOfflineEvaluationReportInfo($info->result_id);
            if ($info->user_dot == 1){
                $info->user_dot = 0;
                $info->save();
            }
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 取消线下预约
     * @param Websocket $websocket
     * @return bool|string
     */
    public function OfflineCancel(Websocket $websocket): bool|string
    {
        $ConsultOfflineModel = new ConsultOfflineModel();
        $ConsultOfflineModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'id|记录ID' => 'require|integer|max:11',
                'cancel_reason|取消理由' => 'require',
            ]);
            $info = $ConsultOfflineModel->with(['ConsultTime'])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->is_end == 1) throw new \Exception('预约已结束！');
            $ConfigModel = new ConfigModel();
            $config = $ConfigModel->where([
                ['unit_id', '=', $this->userData['unit_id']],
                ['key','=','consult']
            ])->value('value');
            $config = json_decode($config,true);
            if ($config['remove_restrictions'] > 0){
                $num = match ($config['remove_restrictions']) {
                    '1' => 1,
                    '2' => 4,
                    '3' => 8,
                    '4' => 24,
                    default => throw new \Exception('系统配置错误！'),
                };
                $time = time() + (3600*$num);
                if ($info['reservation_start_time'] < $time)
                    throw new \Exception('必须在'.$num.'小时前取消！');
            }
            $info->situation = 2;
            $info->cancel_reason = $param['cancel_reason'];
            $info->is_end = 1;
            $info->end_time = time();
            $UserModel = new UserModel();
            $UserModel->where('id','=',$info->consult_id)->inc('consult_offline_num')->save();
            $info->save();
            $ConsultOfflineModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultOffline',
                'content' => [
                    'id' => $info['id'],
                    'type' => 2
                ]
            ]),$websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultOfflineModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线上咨询任务测评结果报告
     * @return bool|string
     */
    public function OnlineReportInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->OnlineReportInfo($id);
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 线下预约任务测评结果报告
     * @return bool|string
     */
    public function OfflineReportInfo(): bool|string
    {
        try {
            $id = $this->request->param('id');
            $ReportService = new ReportService($this->app);
            $data = $ReportService->OfflineReportInfo($id);
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 提交评估
     * @param Websocket $websocket
     * @return bool|string
     */
    public function submitEvaluate(Websocket $websocket): bool|string
    {
        $ConsultTimeModel = new ConsultTimeModel();
        $ConsultTimeModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'time_id|预约时段' => 'require',
            ]);
            $timeInfo = $ConsultTimeModel->find($param['time_id']);
            if (!$timeInfo) throw new \Exception('参数错误！');
            if ($timeInfo['is_reservation'] != 0) throw new \Exception('该时段已被预约！');
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $id = $ConsultEvaluateModel->insertGetId([
                'unit_id' => $this->userData['unit_id'],
                'uid' => $this->userData['id'],
                'consult_id' => $timeInfo['consult_id'],
                'time_id' => $param['time_id'],
                'address' => $timeInfo['address'],
                'time' => time()
            ]);
            $timeInfo->save([
                'is_reservation' => 1,
                'reservation_time' => time(),
                'offline_id' => $id,
                'uid' => $this->userData['id'],
            ]);
            $ConsultTimeModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$timeInfo['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultEvaluate',
                'content' => [
                    'id' => $id,
                ]
            ]),$websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultTimeModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估记录
     * @return bool|string
     */
    public function evaluateLog(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'pageSize|每页显示数量' => 'require'
            ]);
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $where = [];
            if (!empty($param['start_time']) && !empty($param['end_time'])) {
                $where[] = ['time', 'between', [$param['start_time'], $param['end_time']]];
            } else {
                if (!empty($param['start_time'])) {
                    $where[] = ['time', '>=', $param['start_time']];
                }
                if (!empty($param['end_time'])) {
                    $where[] = ['time', '<=', $param['end_time']];
                }
            }
            if (!empty($param['consult_id'])) {
                $where[] = ['consult_id', 'in', $param['consult_id']];
            }
            if (isset($param['situation']) && strlen($param['situation']) > 1) {
                $where[] = ['situation', '=', $param['situation']];
            }
            $query = $ConsultEvaluateModel->where($where);
            $data = $query->with([
                'user',
                'consult',
                'consultTime'
            ])->paginate($param['pageSize'])->toArray();
            $data['ids'] = $query->column('id');
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估详情
     * @return bool|string
     */
    public function evaluateInfo(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $info = $ConsultEvaluateModel->with([
                'consult',
                'consultTime'
            ])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            $info->save([
                'user_dot' => 0
            ]);
            return success($info);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估记录删除
     * @return bool|string
     */
    public function evaluateDel(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param, [
                'id|ID' => 'require'
            ]);
            $ConsultEvaluateModel = new ConsultEvaluateModel();
            $ConsultEvaluateModel->where('id','in',$param['id'])->update([
                'user_del' => 1
            ]);
            return success();
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估可预约时间
     * @return bool|string
     */
    public function evaluateDate(): bool|string
    {
        try {
            $ConsultTimeModel = new ConsultTimeModel();
            $data = $ConsultTimeModel->field('date,is_reservation')->where([
                ['unit_id','=',$this->userData['unit_id']],
                ['model','=',2]
            ])->select()->toArray();
            $date = [];
            foreach ($data as $v) {
                $date[$v['date']][] = $v['is_reservation'];
            }
            $data2 = [];
            foreach ($date as $k => $v) {
                if (in_array(0, $v)) {
                    $data2[] = [
                        'date' => strtotime($k),
                        'is_reservation' => 0,
                    ];
                }else{
                    $data2[] = [
                        'date' => strtotime($k),
                        'is_reservation' => 1,
                    ];
                }
            }
            return success($data2);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估可预约的咨询师
     * @return bool|string
     */
    public function evaluateConsult(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'date|日期' => 'require'
            ]);
            $ConsultTimeModel = new ConsultTimeModel();
            $consult_id = $ConsultTimeModel->where([
                ['unit_id','=',$this->userData['unit_id']],
                ['model','=',2],
                ['date','=',$param['date']]
            ])->distinct(true)->column('consult_id');
            $UserModel = new UserModel();
            $data = $UserModel->field('id,name,avatar')->where('id','in',$consult_id)->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 评估可预约的咨询师排班时间
     * @return bool|string
     */
    public function evaluateConsultTime(): bool|string
    {
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'date|日期' => 'require',
                'consult_id|咨询师' => 'require'
            ]);
            $ConsultTimeModel = new ConsultTimeModel();
            $data = $ConsultTimeModel->where([
                ['unit_id','=',$this->userData['unit_id']],
                ['model','=',2],
                ['date','=',$param['date']],
                ['consult_id','=',$param['consult_id']]
            ])->select()->toArray();
            return success($data);
        } catch (\Exception $e) {
            return error($e->getMessage(), $e->getCode(), [
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

    /**
     * 取消评估预约
     * @param Websocket $websocket
     * @return bool|string
     */
    public function evaluateCancel(Websocket $websocket): bool|string
    {
        $ConsultEvaluateModel = new ConsultEvaluateModel();
        $ConsultEvaluateModel->startTrans();
        try {
            $param = $this->request->param();
            $this->validate($param,[
                'id|记录ID' => 'require|integer|max:11',
                'cancel_reason|取消理由' => 'require',
            ]);
            $info = $ConsultEvaluateModel->with(['ConsultTime'])->find($param['id']);
            if (!$info) throw new \Exception('参数错误！');
            if ($info->is_end == 1) throw new \Exception('预约已结束！');
            $ConfigModel = new ConfigModel();
            $config = $ConfigModel->where([
                ['unit_id', '=', $this->userData['unit_id']],
                ['key','=','consult']
            ])->value('value');
            $config = json_decode($config,true);
            if ($config['remove_restrictions'] > 0){
                $num = match ($config['remove_restrictions']) {
                    '1' => 1,
                    '2' => 4,
                    '3' => 8,
                    '4' => 24,
                    default => throw new \Exception('系统配置错误！'),
                };
                $time = time() + (3600*$num);
                if ($info['reservation_start_time'] < $time)
                    throw new \Exception('必须在'.$num.'小时前取消！');
            }
            $info->situation = 2;
            $info->cancel_reason = $param['cancel_reason'];
            $info->is_end = 1;
            $info->end_time = time();
            $UserModel = new UserModel();
            $UserModel->where('id','=',$info->consult_id)->inc('consult_evaluate_num')->save();
            $info->save();
            $ConsultEvaluateModel->commit();
            //推送socket消息
            $socketServer = new Server();
            $fd = $socketServer->uidGetFd([$info['consult_id']]);
            $socketServer->push($fd,json_encode([
                'type' => 'consultEvaluate',
                'content' => [
                    'id' => $info['id'],
                    'type' => 2
                ]
            ]),$websocket);
            return success();
        } catch (\Exception $e) {
            $ConsultEvaluateModel->rollback();
            return error($e->getMessage(), $e->getCode(),[
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
    }

}